﻿// -----------------------------------------------------------------------
// <copyright file="SystemIoConverter.cs" company="Company">
// Company 2011
// </copyright>
// -----------------------------------------------------------------------


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Company.Common;
using Company.Common.Control;
using Company.IO.Interfaces;
using FileAccess = System.IO.FileAccess;
using FileAttributes = Company.IO.Interfaces.FileAttributes;
using FileMode = System.IO.FileMode;
using FileOptions = System.IO.FileOptions;
using FileShare = System.IO.FileShare;
using SearchOption = System.IO.SearchOption;
using SeekOrigin = System.IO.SeekOrigin;

namespace Company.System.IO
{
    /// <summary>
    /// Converter to convert between the used Types
    /// </summary>
    [Guid("c0d38422-3a7b-41f3-9829-64d97dd4e70e")]
    public class SystemIoConverter : ISystemIoConverter
    {
        #region ISystemIoConverter Members

        /// <summary>
        /// Convert a DirectoryInfo object to <see cref="IDirectoryInfo"/> object
        /// </summary>
        /// <param name="directoryInfo">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IDirectoryInfo ISystemIoConverter.Convert(global::System.IO.DirectoryInfo directoryInfo)
        {
            return Convert(directoryInfo);
        }

        /// <summary>
        /// Convert a DirectoryInfo[] object to <see cref="IDirectoryInfo"/>[] object
        /// </summary>
        /// <param name="directoryInfos">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IDirectoryInfo[] ISystemIoConverter.Convert(global::System.IO.DirectoryInfo[] directoryInfos)
        {
            return Convert(directoryInfos);
        }

        /// <summary>
        /// Convert a IEnumerable DirectoryInfo object to IEnumerable <see cref="IDirectoryInfo"/> object
        /// </summary>
        /// <param name="directoryInfos">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IEnumerable<IDirectoryInfo> ISystemIoConverter.Convert(
            IEnumerable<global::System.IO.DirectoryInfo> directoryInfos)
        {
            return Convert(directoryInfos);
        }

        /// <summary>
        /// Convert a FileInfo object to <see cref="IFileInfo"/> object
        /// </summary>
        /// <param name="fileInfo">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IFileInfo ISystemIoConverter.Convert(global::System.IO.FileInfo fileInfo)
        {
            return Convert(fileInfo);
        }

        /// <summary>
        /// Convert a FileInfo[] object to <see cref="IFileInfo"/>[] object
        /// </summary>
        /// <param name="fileInfos">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IFileInfo[] ISystemIoConverter.Convert(global::System.IO.FileInfo[] fileInfos)
        {
            return Convert(fileInfos);
        }

        /// <summary>
        /// Convert a IEnumerable FileInfo object to IEnumerable <see cref="IFileInfo"/> object
        /// </summary>
        /// <param name="fileInfo">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IEnumerable<IFileInfo> ISystemIoConverter.Convert(IEnumerable<global::System.IO.FileInfo> fileInfo)
        {
            return Convert(fileInfo);
        }

        /// <summary>
        /// Convert a FileSystemInfo object to <see cref="IFileSystemInfo"/> object
        /// </summary>
        /// <param name="fileSystemInfo">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IFileSystemInfo ISystemIoConverter.Convert(FileSystemInfo fileSystemInfo)
        {
            return Convert(fileSystemInfo);
        }

        /// <summary>
        /// Converts the specified file infos.
        /// </summary>
        /// <param name="fileInfos">The file infos.</param>
        /// <returns>the converted object</returns>
        IFileSystemInfo[] ISystemIoConverter.Convert(FileSystemInfo[] fileInfos)
        {
            return Convert(fileInfos);
        }

        /// <summary>
        /// Convert a IEnumerable FileSystemInfo object to IEnumerable <see cref="IFileSystemInfo"/> object
        /// </summary>
        /// <param name="fileSystemInfo">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IEnumerable<IFileSystemInfo> ISystemIoConverter.Convert(IEnumerable<FileSystemInfo> fileSystemInfo)
        {
            return Convert(fileSystemInfo);
        }

        /// <summary>
        /// Convert a SearchOption object to <see cref="Company.IO.Interfaces.SearchOption"/> object
        /// </summary>
        /// <param name="searchOption">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        SearchOption ISystemIoConverter.Convert(Company.IO.Interfaces.SearchOption searchOption)
        {
            return Convert(searchOption);
        }

        /// <summary>
        /// Convert a FileAttributes object to <see cref="FileAttributes"/> object
        /// </summary>
        /// <param name="fileAttributes">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        FileAttributes ISystemIoConverter.Convert(global::System.IO.FileAttributes fileAttributes)
        {
            return Convert(fileAttributes);
        }

        /// <summary>
        /// Convert a <see cref="FileAttributes"/> object to FileAttributes object
        /// </summary>
        /// <param name="fileAttributes">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        global::System.IO.FileAttributes ISystemIoConverter.Convert(FileAttributes fileAttributes)
        {
            return Convert(fileAttributes);
        }

        /// <summary>
        /// Convert a FileShare object to <see cref="Company.IO.Interfaces.FileShare"/> object
        /// </summary>
        /// <param name="share">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        FileShare ISystemIoConverter.Convert(Company.IO.Interfaces.FileShare share)
        {
            return Convert(share);
        }

        /// <summary>
        /// Convert a FileAccess object to <see cref="Company.IO.Interfaces.FileAccess"/> object
        /// </summary>
        /// <param name="access">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        FileAccess ISystemIoConverter.Convert(Company.IO.Interfaces.FileAccess access)
        {
            return Convert(access);
        }

        /// <summary>
        /// Convert a FileMode object to <see cref="Company.IO.Interfaces.FileMode"/> object
        /// </summary>
        /// <param name="mode">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        FileMode ISystemIoConverter.Convert(Company.IO.Interfaces.FileMode mode)
        {
            return Convert(mode);
        }

        /// <summary>
        /// Convert a Stream object to <see cref="IStream"/> object
        /// </summary>
        /// <param name="stream">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IStream ISystemIoConverter.Convert(global::System.IO.Stream stream)
        {
            return Convert(stream);
        }

        /// <summary>
        /// Convert a StreamReader object to <see cref="IStreamReader"/> object
        /// </summary>
        /// <param name="streamReader">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IStreamReader ISystemIoConverter.Convert(global::System.IO.StreamReader streamReader)
        {
            return Convert(streamReader);
        }

        /// <summary>
        /// Convert a StreamWriter object to <see cref="IStreamWriter"/> object
        /// </summary>
        /// <param name="streamWriter">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        IStreamWriter ISystemIoConverter.Convert(global::System.IO.StreamWriter streamWriter)
        {
            return Convert(streamWriter);
        }

        /// <summary>
        /// Converts the specified origin.
        /// </summary>
        /// <param name="origin">The origin.</param>
        /// <returns>
        /// the converted object
        /// </returns>
        SeekOrigin ISystemIoConverter.Convert(Company.IO.Interfaces.SeekOrigin origin)
        {
            return Convert(origin);
        }

        /// <summary>
        /// Converts the specified options.
        /// </summary>
        /// <param name="options">The options.</param>
        /// <returns>
        /// The converted object
        /// </returns>
        FileOptions ISystemIoConverter.Convert(Company.IO.Interfaces.FileOptions options)
        {
            return Convert(options);
        }

        /// <summary>
        /// Converts the specified exception.
        /// </summary>
        /// <param name="exception">The exception.</param>
        /// <returns>The converted object</returns>
        IException ISystemIoConverter.Convert(global::System.Exception exception)
        {
            return Convert(exception);
        }

        #endregion

        /// <summary>
        /// Convert a DirectoryInfo object to <see cref="IDirectoryInfo"/> object
        /// </summary>
        /// <param name="directoryInfo">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IDirectoryInfo Convert(global::System.IO.DirectoryInfo directoryInfo)
        {
            return new DirectoryInfo(this, directoryInfo);
        }

        /// <summary>
        /// Convert a DirectoryInfo[] object to <see cref="IDirectoryInfo"/>[] object
        /// </summary>
        /// <param name="directoryInfos">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IDirectoryInfo[] Convert(global::System.IO.DirectoryInfo[] directoryInfos)
        {
            int length = directoryInfos.Length;
            var result = new IDirectoryInfo[length];

            Loop.For(0, length, (i) => { result[i] = Convert(directoryInfos[i]); });

            return result;
        }

        /// <summary>
        /// Convert a IEnumerable DirectoryInfo object to IEnumerable <see cref="IDirectoryInfo"/> object
        /// </summary>
        /// <param name="directoryInfos">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IEnumerable<IDirectoryInfo> Convert(IEnumerable<global::System.IO.DirectoryInfo> directoryInfos)
        {
            return directoryInfos.Select(Convert);
        }

        /// <summary>
        /// Convert a FileInfo object to <see cref="IFileInfo"/> object
        /// </summary>
        /// <param name="fileInfo">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IFileInfo Convert(global::System.IO.FileInfo fileInfo)
        {
            return new FileInfo(this, fileInfo);
        }

        /// <summary>
        /// Convert a FileInfo[] object to <see cref="IFileInfo"/>[] object
        /// </summary>
        /// <param name="fileInfos">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IFileInfo[] Convert(global::System.IO.FileInfo[] fileInfos)
        {
            int length = fileInfos.Length;
            var result = new IFileInfo[length];

            Loop.For(0, length, (i) => { result[i] = Convert(fileInfos[i]); });

            return result;
        }

        /// <summary>
        /// Convert a IEnumerable FileInfo object to IEnumerable <see cref="IFileInfo"/> object
        /// </summary>
        /// <param name="fileInfo">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IEnumerable<IFileInfo> Convert(IEnumerable<global::System.IO.FileInfo> fileInfo)
        {
            return fileInfo.Select(Convert);
        }

        /// <summary>
        /// Convert a FileSystemInfo object to <see cref="IFileSystemInfo"/> object
        /// </summary>
        /// <param name="fileSystemInfo">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IFileSystemInfo Convert(FileSystemInfo fileSystemInfo)
        {
            // return new FileSystemInfo(this, fileSystemInfo);
            throw new NotImplementedException();
        }

        /// <summary>
        /// Convert a FileSystemInfo[] object to <see cref="IFileSystemInfo"/>[] object
        /// </summary>
        /// <param name="fileSystemInfos">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IFileSystemInfo[] Convert(FileSystemInfo[] fileSystemInfos)
        {
            int length = fileSystemInfos.Length;
            var result = new IFileSystemInfo[length];

            Loop.For(0, length, (i) => { result[i] = Convert(fileSystemInfos[i]); });

            return result;
        }

        /// <summary>
        /// Convert a IEnumerable FileSystemInfo object to IEnumerable <see cref="IFileSystemInfo"/> object
        /// </summary>
        /// <param name="fileSystemInfo">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IEnumerable<IFileSystemInfo> Convert(IEnumerable<FileSystemInfo> fileSystemInfo)
        {
            return fileSystemInfo.Select(Convert);
        }

        /// <summary>
        /// Convert a SearchOption object to <see cref="Company.IO.Interfaces.SearchOption"/> object
        /// </summary>
        /// <param name="searchOption">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private SearchOption Convert(Company.IO.Interfaces.SearchOption searchOption)
        {
            return (SearchOption) searchOption;
        }

        /// <summary>
        /// Convert a FileAttributes object to <see cref="FileAttributes"/> object
        /// </summary>
        /// <param name="fileAttributes">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private FileAttributes Convert(global::System.IO.FileAttributes fileAttributes)
        {
            return (FileAttributes) fileAttributes;
        }

        /// <summary>
        /// Convert a <see cref="FileAttributes"/> object to FileAttributes object
        /// </summary>
        /// <param name="fileAttributes">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private global::System.IO.FileAttributes Convert(FileAttributes fileAttributes)
        {
            return (global::System.IO.FileAttributes) fileAttributes;
        }

        /// <summary>
        /// Convert a FileShare object to <see cref="Company.IO.Interfaces.FileShare"/> object
        /// </summary>
        /// <param name="share">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private FileShare Convert(Company.IO.Interfaces.FileShare share)
        {
            return (FileShare) share;
        }

        /// <summary>
        /// Convert a FileAccess object to <see cref="Company.IO.Interfaces.FileAccess"/> object
        /// </summary>
        /// <param name="access">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private FileAccess Convert(Company.IO.Interfaces.FileAccess access)
        {
            return (FileAccess) access;
        }

        /// <summary>
        /// Convert a FileMode object to <see cref="Company.IO.Interfaces.FileMode"/> object
        /// </summary>
        /// <param name="mode">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private FileMode Convert(Company.IO.Interfaces.FileMode mode)
        {
            return (FileMode) mode;
        }

        /// <summary>
        /// Convert a Stream object to <see cref="IStream"/> object
        /// </summary>
        /// <param name="stream">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IStream Convert(global::System.IO.Stream stream)
        {
            return new Stream(this, stream);
        }

        /// <summary>
        /// Convert a StreamReader object to <see cref="IStreamReader"/> object
        /// </summary>
        /// <param name="streamReader">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IStreamReader Convert(global::System.IO.StreamReader streamReader)
        {
            return new StreamReader(this, streamReader);
        }

        /// <summary>
        /// Convert a StreamWriter object to <see cref="IStreamWriter"/> object
        /// </summary>
        /// <param name="streamWriter">The given object to convert</param>
        /// <returns>
        /// The converted object
        /// </returns>
        private IStreamWriter Convert(global::System.IO.StreamWriter streamWriter)
        {
            return new StreamWriter(this, streamWriter);
        }

        /// <summary>
        /// Converts the specified origin.
        /// </summary>
        /// <param name="origin">The origin.</param>
        /// <returns>the converted object</returns>
        private SeekOrigin Convert(Company.IO.Interfaces.SeekOrigin origin)
        {
            return (SeekOrigin) origin;
        }

        /// <summary>
        /// Converts the specified options.
        /// </summary>
        /// <param name="options">The options.</param>
        /// <returns>The converted object</returns>
        private FileOptions Convert(Company.IO.Interfaces.FileOptions options)
        {
            return (FileOptions) options;
        }

        /// <summary>
        /// Converts the specified exception.
        /// </summary>
        /// <param name="exception">The exception.</param>
        /// <returns>The converted object</returns>
        private IException Convert(global::System.Exception exception)
        {
            return new Exception(this, exception);
        }
    }
}